#include <iostream>
#include <fstream>
#include <sstream>
#include <chrono>
#include "Job.cpp"
#include "SA.cpp"
#include "GA.cpp"

std::vector<std::vector<std::vector<int>>> parseDataFile(const std::string& filename);

int main() {
    std::string filename = "data.txt";
    std::vector<std::vector<std::vector<int>>> dataGroups = parseDataFile(filename);    // 读取数据
    // 根据数据组生成对应工作流水线
    for (int i = 0; i < dataGroups.size(); ++i) {
        // 导入数据生成实例
        Job job(dataGroups[i], i);
        std::cout << "\n[" <<job.getSerial() << ']' << std::endl;

        // 模拟退火算法
        std::cout << "SA:" << std::endl;
        auto startSA = std::chrono::high_resolution_clock::now(); // 模拟退火算法开始时间

        SA sa(1000, 0.001, 0.99, 100);  // 模拟退火算法参数
        sa.run(job);    // 算法进行

        auto endSA = std::chrono::high_resolution_clock::now();   // 模拟退火算法结束时间
        std::chrono::duration<double> timesSA = endSA - startSA;

        // 模拟退火算法结果
        std::cout << job.makespan(job.getRank()) << ' ' << timesSA.count() << std::endl;
        job.printRank();

        // 遗传算法
        std::cout << "GA:" << std::endl;
        auto startGA = std::chrono::high_resolution_clock::now();   // 遗传算法开始时间

        GA ga(20, job.getN(), 0.8, 0.4, 100);    // 遗传算法参数
        ga.run(job);    // 算法进行

        auto endGA = std::chrono::high_resolution_clock::now();     // 遗传算法开始时间
        std::chrono::duration<double> timesGA = endGA - startGA;

        // 遗传算法结果
        std::cout << job.makespan(job.getRank()) << ' ' << timesGA.count() << std::endl;
        job.printRank();
    }

    return 0;
}

std::vector<std::vector<std::vector<int>>> parseDataFile(const std::string& filename) {
    std::ifstream file(filename);
    // 检查存储数据的文件是否正常打开
    if (!file.is_open()) {
        std::cerr << "Error opening file: " << filename << std::endl;
        return {};
    }
    // 定义相关变量
    std::string line;   // 当前行
    std::vector<std::vector<std::vector<int>>> dataGroups;  // 总的数据组
    std::vector<std::vector<int>> currentGroup; // 当前阅读数据组
    // 遍历文件每一行
    while (std::getline(file, line)) {
        // 跳过非数字开头的行
        if (!line.empty() && std::isdigit(line[0])) {
            // 读取n和m的数据
            int n, m;
            std::istringstream nums(line);  // 将string转换为num
            nums >> n >> m;
            // 定义currentGroup数据大小
            currentGroup.resize(n, std::vector<int>(m, 0));
            // 读取n行数据
            for (int i = 0; i < n; ++i) {
                std::getline(file, line);   // 读取下一行
                std::istringstream numsLine(line);
                // 将2 * m个数据转换为m个键对，我们只需要其中的value
                for (int j = 0; j < m; ++j) {
                    int key, value;
                    numsLine >> key >> value;
                    currentGroup[i][j] = value;
                }
            }
            dataGroups.push_back(currentGroup);
            currentGroup.clear();   // 清理以便处理下一组数据
        }
    }
    return dataGroups;
}
